/**
    鸭子类型：面向接口编程，而不是不面向实现编程。
*/
var duck = {
    duckSinging: function() {
        console.log('嘎嘎嘎！')
    }
};

var chicken = {
    duckSinging: function() {
        console.log('嘎嘎嘎！')
    }
};

var choir = [];
var joinChoir = function(animal) {
    if (animal && typeof animal.duckSinging === 'function') {
        choir.push(animal);
        console.log('恭喜加入合唱团;' + choir.length);
    }
};

// joinChoir(duck);
// joinChoir(chicken);



/**
    多态：同一操作在不同的对象上可以产生不同的解释与结果。（给不同的对象发出相同的指令时，这些对象给出不同的反馈）。
    多态的思想是：将'不变的事物'与'可变的事物'分离开来，动物都会叫是不变的，但不同的动物具体怎么叫是可变的。把不变的部分分隔出来，把可变的部分封装起来，给予程序扩展能力，也符合开放-封闭原则。
*/

/* // 多态的javascript代码
var makeSound = function (animal) {
    if (animal instanceof Duck) {
        console.log('嘎嘎嘎嘎！')
    } else if (animal instanceof Chicken) {
        console.log('咯咯咯咯！')
    }
}

var Duck = function () {};
var Chicken = function() {};
makeSound(new Duck());
makeSound(new Chicken());
*/



/* // 对象的多态性
// 在电影的拍摄现场，当导演喊出“action”时，主角开始背台词，照明师负责打灯光，后面的群众演员假装中枪倒地，道具师往镜头里撒上雪花。在得到同一个消息时，每个对象都知道自己应该做什么。如果不利用对象的多态性，而是用面向过程的方式来编写这一段代码，那么相当于在电影开始拍摄之后，导演每次都要走到每个人的面前，确认它们的职业分工（类型），然后告诉他们要做什么。如果映射到程序中，那么程序中将充斥着条件分支语句。
var animalSound = function(animal) {
    animal.sound()
};

var Duck = function() {};
Duck.prototype.sound = function() {
    console.log('嘎嘎嘎~~')
}
var Chicken = function() {};
Chicken.prototype.sound = function() {
    console.log('咯咯咯咯~~')
}
animalSound(new Duck());
animalSound(new Chicken());
*/

var googleMap = {
    show: function() {
        console.log('开始渲染谷歌地图');
    }
}

var baiduMap = {
    show: function() {
        console.log('开始熏染百度地图')
    }
}

// 在添加多种地图后，必须还要继续修改renderMap方法
// var renderMap = function(type) {
//  if (type === 'google') {
//      googleMap.show()
//  } else if (type === 'baidu') {
//      baiduMap.show()
//  }
// }
// renderMap('google')

var sosoMap = {
    show: function() {
        console.log('soso地图')
    }
}

var renderMap = function(map) {
    if (map.show instanceof Function) {
        map.show();
    }
}

renderMap(baiduMap)